/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package assignment2;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.table.DefaultTableModel;

/**
 * InventoryOrderer Class:
 * This class is used to display the number of inventory items that must be ordered to cover the number of products that are scheduled, combined with the number of inventory
 * items currently in stock.
 * @author Vale
 *
 */
public class InventoryOrderer implements ActionListener, WindowListener {

    private JFrame viewInvFrame;
    private JScrollPane table;
    private JPanel headingPanel;
    private JPanel buttonPanel;
    private InventoryList inventory;
    private InventoryList inventoryRestore;
    private JButton closeButton;
    private JTable invTable;
    private ProductList products;
    private DefaultTableModel invTableModel = new DefaultTableModel();
    private static final String HEADING_FONT = "Heading";
    private static final int HEADING_FONT_SIZE = 20;
    private static final String FRAME_HEADING = "Inventory Order";
    private static final String GUI_TITLE = "Inventory Required for Order";
    private static final String CLOSE_BUTTON = "Close";
    private static final int FRAME_WIDTH = 400;
    private static final int FRAME_HEIGHT = 500;
    private static final int BPANEL_ROWS = 3;
    private static final int BPANEL_COLS = 2;
    private static final int BUTTON_SPACING = 5;
    private static final int TABLE_COLS = 2;
    private static final String TABLE_HEAD_COL1 = "Inventory Item";
    private static final String TABLE_HEAD_COL2 = "Amount to be Ordered";
    private static final int ZERO = 0;

    /**
     * InventoryOrderer Constructor:
     * This is the constructor for the InventoryOrderer class. It takes the current inventory list and product lists as inputs. which are use to determine the required number of
     * each inventory item that are required to produce the scheduled products.
     *
     */
    public InventoryOrderer(InventoryList invList, ProductList prodList) {
        //Create new Objects
        inventory = invList;
        products = prodList;
        inventoryRestore = invList;
        viewInvFrame = new JFrame(FRAME_HEADING);
        headingPanel = new JPanel();
        buttonPanel = new JPanel();
        closeButton = new JButton(CLOSE_BUTTON);

        //Edit Frames properties
        viewInvFrame.addWindowListener(this);
        viewInvFrame.setResizable(false);
        viewInvFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        viewInvFrame.setLayout(new BorderLayout());

        //Format Heading
        JTextArea heading = new JTextArea(GUI_TITLE);
        Color bgColour = viewInvFrame.getBackground();
        heading.setBackground(bgColour);
        Font headerFont = new Font(HEADING_FONT, Font.BOLD, HEADING_FONT_SIZE);
        heading.setFont(headerFont);
        headingPanel.add(heading);

        //Add Buttons
        buttonPanel.add(closeButton);
        closeButton.addActionListener(this);

        //Print main Product table
        printInvTable();

        //Add content to frame
        viewInvFrame.getContentPane().add(headingPanel, BorderLayout.NORTH);
        viewInvFrame.getContentPane().add(table, BorderLayout.CENTER);
        viewInvFrame.getContentPane().add(buttonPanel,BorderLayout.SOUTH);
        viewInvFrame.setVisible(true);
        viewInvFrame.pack();

}

    /**
     * int getRequiredInventory(int invListIndex) Method:
     * This method is used to get the required inventory for each different inventory item. It does this by searching each product in the product list to determine
     * if the product requires the inventory item, and if so, increments the inventory required.
     * @param The index of the inventory item in the inventory list array
     * @return returns the number of inventory items required to produce the scheduled products
     *
     */
    public int getRequiredInventory(int invListIndex) {
        Inventory invItem = inventory.get(invListIndex);
        InventoryList prodInvList;

        for (int j = 0; j < inventory.size(); j++) {
            inventory.get(j).setInvReqd(ZERO);
        }
        for (int i = ZERO; i < products.size(); i++) {
            prodInvList = products.get(i).getInventList();
            try {
            for (int k = 0; k < prodInvList.size(); k++) {
                if (prodInvList.get(k).getInvName().equals(invItem.getInvName())) {
                    invItem.setInvReqd(invItem.getInvReqd() + products.get(i).getProdSched());
                } else {
                    continue;
                }
            }
        } catch (Exception x) {
            continue;
        }
        }
        return inventory.get(invListIndex).getInvReqd();
    }

    /**
     * void printInvTable() Method:
     * This method is used to print the table of inventory items that currently exist in the list, along with the specific information for each item. It also disables direct
     * editing of the table itself.
     *
     */
    private void printInvTable() {
        int tableSize = inventory.getInvList().size();
        Object[][] rowData = new Object[tableSize][TABLE_COLS];
        Object[] columnNames = {TABLE_HEAD_COL1, TABLE_HEAD_COL2};
        for (int i = ZERO; i < tableSize; i++) {
            Object[] rowNum = {inventory.getInvList().get(i).getInvName(),getRequiredInventory(i)-inventory.getInvList().get(i).getInvStock()};
            rowData[i] = rowNum;
        }
        invTable = new JTable(invTableModel) {
            public boolean isCellEditable(int rowIndex, int colIndex) {
                return false;
            }
        };
        invTableModel.setDataVector(rowData, columnNames);
        invTable.setRowSelectionAllowed(true);

        table = new JScrollPane(invTable);

    }

    /**
     * void actionPerformed(ActionEvent e) Method:
     * This is called when the "Close" button is pressed. It calls dispose(), which frees up all currently used resources by the current frame (viewProdFrame)
     * and consequently closes it.
     *
     */
    public void actionPerformed(ActionEvent e) {
        viewInvFrame.dispose();
    }

    /**
     * void windowOpened(WindowEvent e) Method:
     * This is one of the abstract methods of the WindowListener class. It has not been implemented.
     *
     */
    public void windowOpened(WindowEvent e) {
    }

    /**
     * void windowClosing(WindowEvent e) Method:
     * This is one of the abstract methods of the WindowListener class. It has been implemented such that if the frame is closed without using the specified "Back"
     * button, the resources used by the frame are released.
     *
     */
    public void windowClosing(WindowEvent e) {
       viewInvFrame.dispose();
    }

    /**
     * void windowClosed(WindowEvent e) Method:
     * This is one of the abstract methods of the WindowListener class. It has not been implemented, as its purpose has been covered by the 'windowClosing' event.
     *
     */
    public void windowClosed(WindowEvent e) {
    }

    /**
     * void windowIconified(WindowEvent e) Method:
     * This is one of the abstract methods of the WindowListener class. It has not been implemented.
     *
     */
    public void windowIconified(WindowEvent e) {
    }

    /**
     * void windowDeiconified(WindowEvent e) Method:
     * This is one of the abstract methods of the WindowListener class. It has not been implemented.
     *
     */
    public void windowDeiconified(WindowEvent e) {
    }

    /**
     * void windowActivated(WindowEvent e) Method:
     * This is one of the abstract methods of the WindowListener class. It has not been implemented.
     *
     */
    public void windowActivated(WindowEvent e) {

    }

    /**
     * void windowDeactivated(WindowEvent e) Method:
     * This is one of the abstract methods of the WindowListener class. It has not been implemented.
     *
     */
    public void windowDeactivated(WindowEvent e) {
    }
}
